/*
 *   Clovis
 *   Copyright (C) 2008 SFWOL
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */


#ifndef __CFLOAT_H
#define __CFLOAT_H

#include <string>
#include <sstream>
#include <iostream>
#include "ClovisVariable.h"
#include "CInteger.h"
#include "CString.h"

namespace clovis {

	namespace core {

		class CString;

		class CInteger;

		/*!
		 * The different methods to convert types
		 */
		enum CONVERSION_METHOD {

			//! The most accurate method
			NEAREST,

			//! Simply remove the point
			TRUNCATE

		};

		/*!
		 * \brief The main Integer type used into Clovis
		 *
		 * CFloat is the float type used into Clovis. It has the same value as an int but with
		 * usefull methods that you can call averywhere in your source code.
		 * You can use it as a standard type.
		 * \code
		 * CFloat my_var = 10.5;
		 * \endcode
		 */
		class CFloat : public ClovisVariable {

			private:

				float value;	// Internal value

			public:

                float get();	// Method to call the internal value of a CFloat

                /*!
                 * Constructeur ou l'on souhaite attribuer un nom
                 * \arg Le nom de l'objet
                 * \arg La valeur de l'objet
                 */
                CFloat(std::string name , float value);


				/*!
				 * Objected oriented constructor
				 * \code
				 * CFloat my_var(10.5);
				 * \endcode
				 */
				CFloat(float value);

				/*!
				 * Standard type constructor
				 * \code
				 * CFloat my_var = 10.5;
				 * \endcode
				 */
				CFloat();

				/*!
				 * Get The class type in a std::string variable.
				 * \return "CFloat"
				 */
				std::string getClass();

				/*!
				 * To change the value with a standard int
				 * \arg value The value to assign
				 */
				void operator = (float value);

				/*!
				 * To change the value with a CFloat
				 * \arg value The value to assign
				 */
				void operator = (CFloat value);

				/*!
				 * + operator
				 * \return A new CFloat where the internal value is the sum of the current CFloat and the 'value' argument
				 */
				CFloat operator + (CFloat value);

				/*!
				 * - operator
				 * \return A new CFloat where the internal value is the substraction of the current CFloat and the 'value' argument
				 */
				CFloat operator - (CFloat value);

				/*!
				 * + operator
				 * \return A new CFloat where the internal value is the multiplication of the current CFloat and the 'value' argument
				 */
				CFloat operator * (CFloat value);

				/*!
				 * + operator
				 * \return A new CFloat where the internal value is the division of the current CFloat and the 'value' argument
				 */
				CFloat operator / (CFloat value);

				/*!
				 * return the standard float value of the current CFloat.
				 / \return A float value.
				 */
				float toFloat();

				/*!
				 * Get the current value as a std::string value.
				 * \return A std::string value.
				 */
				std::string toString();

				/*!
				 * Get the current value as a CString.
				 * \return A CString representation of the current value.
				 */
				CString toCString();

				/*!
				 * Convert the current value to CInteger and return it.
				 * For exemple the following code :
				 * \code
				 * Float var;
				 * CInteger foo;
				 *
				 * var = 10.2;
				 * foo = var.toCInteger(NEAREST); // Or : var.toCInteger()
				 * std::cout << var.toFloat() << " -> " << foo.toInt() << std::endl;
				 *
				 * var = 10.8;
				 * foo = var.toCInteger(NEAREST); // Or : var.toCInteger()
				 * std::cout << var.toFloat() << " -> " << foo.toInt() << std::endl;
				 *
				 * var = 10.2;
				 * foo = var.toCInteger(TRUNCATE);
				 * std::cout << var.toFloat() << " -> " << foo.toInt() << std::endl;
				 *
				 * var = 10.8;
				 * foo = var.toCInteger(TRUNCATE);
				 * std::cout << var.toFloat() << " -> " << foo.toInt() << std::endl;
				 * \endcode
				 * Will return :
				 * \code
				 * 10.2 -> 10
				 * 10.8 -> 11
				 * 10.2 -> 10
				 * 10.8 -> 10
				 * \endcode
				 * \return A Cinteger value of the current CFloat.
				 */
				CInteger toCInteger(CONVERSION_METHOD method = NEAREST);

		};

	};

};

#endif
